<template>
  <div>
    <!--页面内容-->
    <el-row>
      <el-col class="rich-container" :span="22" :offset="1">
        <card cardName="使用富文本编辑器" cardWidth='100%' :scalable="false">
          <div slot="tool" class="toggle-editor" v-show="$route.query.id == undefined">
            <p @click="toMarkdown">切换为markdown编辑器 >>></p>
          </div>

          <div slot="content">
            <h4>标题</h4>
            <div class="title-container">
              <el-input placeholder="请输入标题" class="input-title" maxlength="50" v-model="entity.articleTitle"></el-input>
              <div class="select-container">
                <el-select v-model="entity.selectedType" placeholder="请选择" class="type-select">
                  <el-option
                    v-for="item in typeData"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value">
                  </el-option>
                </el-select>
                <el-select v-model="entity.selectedCategory" placeholder="请选择文章分类" class="category-select">
                  <el-option
                    v-for="item in categoryData"
                    :key="item.id"
                    :label="item.categoryName"
                    :value="item.id">
                  </el-option>
                </el-select>
                <el-select v-model="entity.selectedTag" placeholder="请选择文章标签" class="tag-select" filterable collapse-tags multiple>
                  <el-option
                    v-for="item in tagData"
                    :key="item.id"
                    :label="item.tagName"
                    :value="item.id">
                  </el-option>
                </el-select>
              </div>
            </div>
            <h4>内容</h4>
            <div id="websiteEditorElem"></div>
            <!--保存按钮-->
            <div class="button-container">
              <el-button type="info" @click="$router.go(-1)">返回</el-button>
              <el-button type="primary" @click="chooseCover">保存</el-button>
            </div>
          </div>
        </card>
      </el-col>
    </el-row>
    <!--选择封面的模态框-->
    <select-cover-template
      :entityFromParent="entity"
      @confirmCover="confirmCover"
      ref="selectCoverTemplate">
    </select-cover-template>
  </div>
</template>

<script>
  import E from 'wangeditor';
  import Card from 'components/common/card/Card';
  import SelectCoverTemplate from './SelectCoverTemplate';

  import {getAllCategory} from "../../../network/viewsRequest/category";
  import {getTagByCid} from "../../../network/viewsRequest/tag";
  import {insertArticle, updateArticle, getArticleById} from "../../../network/viewsRequest/article";

  import {IMAGE_SERVER_URL, WRITTEN_BY_RICHEDITOR, PATH_SERVER_PLACEHOLDER} from "../../../common/const";

  export default {
    name: "RichEditorView",
    data() {
      return {
        entity: { // 接收或保存信息的实体
          id: 0, // 文章id
          articleTitle: '', // 文章标题
          articleContent: '', // 编辑器中的内容
          editorType: WRITTEN_BY_RICHEDITOR,
          release: 0,
          ifExistedInCarousel: null,
          optionFlag: -1,
          selectedType: 1,
          selectedCategory: '',
          selectedTag: [],
          selectedCoverUrl: '', // 文章封面的url
          summary: '',
        },
        typeData: [{
          value: 1,
          label: '原创'
        }, {
          value: 2,
          label: '转载'
        }],
        categoryData: [],
        tagData: [],
        imageList: [], // 作为封面候选的所有图片链接的集合
      }
    },
    methods: {
      /**
       * 保存文章的方法
       */
      saveArticle() {
        // 1.选择操作的方法，是新增还是修改
        let func = null;
        if (this.entity.id == 0) { // 新增
          func = insertArticle;
        } else { // 修改
          func = updateArticle;
        }
        // 2.进行操作
        this.$confirm('确定要保存吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          // 3.获取编辑器中的内容
          let rawContent = this.getContent();
          /*
            将编辑器中的内容中img标签的src属性里涉及到本项目的图片的地址进行替换，替换的示例如下：
                <img src="http://www.baidu.com/123.jpg">
              这里的http://www.baidu.com是图片服务器的主机，对应常量是IMAGE_SERVER_URL
              替换后的结果为：
                <img src="__%PATH_SERVER_PLACEHOLDER%__/image/123.jpg">
              这里的__%PATH_SERVER_PLACEHOLDER%__是占位符，对应的常量是IMAGE_SERVER_URL
           */
          let regExp = new RegExp(`${IMAGE_SERVER_URL}`, "ig");
          this.entity.articleContent = rawContent.replace(regExp, PATH_SERVER_PLACEHOLDER);
          func(this.entity).then(res => {
            if (res.code == 1) {
              this.$message({
                type: 'success',
                message: '保存成功！'
              });
              // 跳转会文章列表
              this.$router.push("/dashboard/article");
            } else {
              this.$message({
                type: 'error',
                message: res.message
              })
            }
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '保存操作已被取消'
          });
        });


      },
      /**
       * 对需要保存的内容进行前端校验
       */
      validEntity() {
        // 1.检查标题
        if (this.entity.articleTitle == null || this.entity.articleTitle.trim().length == 0) {
          this.$message({
            type: 'error',
            message: '请输入文章标题',
          });
          return false;
        }
        // 2.检查内容
        if (this.getContent() == null || this.getContent().trim().length == 0) {
          this.$message({
            type: 'error',
            message: '文章内容不能为空',
          });
          return false;
        }
        // 3.检查有没有选择分类
        if (this.entity.selectedCategory == '') {
          this.$message({
            type: 'error',
            message: '请选择文章的分类',
          });
          return false;
        }
        // 4.检查有没有选择标签
        if (this.entity.selectedTag.length == 0) {
          this.$message({
            type: 'error',
            message: '请选择文章的标签',
          });
          return false;
        }
        return true;
      },
      /**
       * 点击`保存`按钮调用的方法，弹出模态框
       */
      chooseCover() {
        // 1.对保存的内容进行校验
        if (!this.validEntity()) {
          return false;
        }
        // 2.打开模态框
        this.$modal.show('selectCoverModal');
      },
      /**
       * 用户选择了封面后调用的方法
       * @param coverUrl 用户已经选择的封面图片的url
       * @param release 该文章是否保存后直接发布，1发布，0不发布
       * @param optionFlag 是否需要将文章在轮播图中进行操作，0不需要，1新增轮播图，2修改轮播图，3删除轮播图
       */
      confirmCover(coverUrl, release, summary, optionFlag) {
        // 给封面信息赋值
        if (coverUrl != null && coverUrl != '') {
          this.entity.selectedCoverUrl = coverUrl;
        } else { // 没有封面不给过
          this.$message.error("未选择文章的封面");
          return;
        }
        // 给简介赋值
        if (summary != null && summary != '') {
          this.entity.summary = summary;
        } else { // 没有简介不给过
          this.$message.error("您还未输入文章简介");
          return;
        }
        // 给是否发布赋值
        if (release != null) {
          this.entity.release = release;
        }
        if (optionFlag != -1) {
          this.entity.optionFlag = optionFlag;
        }

        // 关闭模态框
        this.$refs.selectCoverTemplate.closeModal();
        // 保存信息
        this.saveArticle();
      },
      /**
       * 向wangeditor中设置内容
       * @param val 需要设置的内容
       */
      setContent(val) {　　　　//设置内容
        this.editor.$txt.html(val)
      },
      /**
       * 清空wangeditor中的内容
       */
      clearContent() {　　　　//清空内容
        // this.editor.txt.clear()
        this.editor.$txt.html(this.editorDefault)
      },
      /**
       * 获取wangeditor中的内容
       */
      getContent() {　　　　　　//获取内容
        let content = this.editor.$txt.html()
        if (content.replace("<p><br></p>","").trim() != "") {
          return this.editor.$txt.html()
        }else{
          return ""
        }
      },
      /**
       * 初始化富文本编辑器
       */
      initWangEditor() {
        this.editor = new E('websiteEditorElem');
        this.editor.$editorContainer.css('z-index', 20); // 去除报错
        // 设置初始化参数
        this.editor.config.pasteFilter = true; // 样式过滤
        this.editor.config.uploadImgUrl = 'http://api.tsinglog.online/upload/uploadImage'; //上传图片controller
        this.editor.config.uploadImgFileName = 'file'; // 上传时file对应的值，即springmvc中MultipartFile参数对应的参数名
        this.editor.config.uploadHeaders = { // 添加用于认证的请求头
          'Authorization': `Bearer ${this.$store.state.token}`
        };
        this.editor.config.printLog = false; // 关闭提示的打印

        // 图片上传的方法
        this.editor.config.uploadImgFns.onload = (resultText, xhr) =>{
          // resultText 服务器端返回的text
          // xhr 是 xmlHttpRequest 对象，IE8、9中不支持

          // 上传图片时，已经将图片的名字存在 editor.uploadImgOriginalName
          // var originalName = this.editor.uploadImgOriginalName || '';
          if (JSON.parse(resultText).code == 1) {
            // 如果 resultText 是图片的url地址，可以这样插入图片：
            const url = JSON.parse(resultText).data.imgUrl;
            // this.editor.command(null, 'insertHtml', '<img src="' + url + '" style="max-width:100%;"/>');
            // 如果不想要 img 的 max-width 样式，也可以这样插入：
            this.editor.command(null, 'insertImage', IMAGE_SERVER_URL + url);
          } else {
            this.$message.error(JSON.parse(resultText).message);
          }

        };

        // 自定义timeout事件
        this.editor.config.uploadImgFns.ontimeout = function (xhr) {
          // xhr 是 xmlHttpRequest 对象，IE8、9中不支持
          alert('上传超时');
        };

        // 自定义error事件
        this.editor.config.uploadImgFns.onerror = function (xhr) {
          // xhr 是 xmlHttpRequest 对象，IE8、9中不支持
          alert('上传错误' + xhr);
        };

        // 创建富文本编辑器
        this.editor.create();
        // 给富文本编辑器设置初始值
        this.editor.$txt.html(this.editorDefault);
      },
      /**
       * 获取所有分类信息
       */
      getAllCategory() {
        getAllCategory().then(res => {
          if (res.code == 1) {
            this.categoryData = res.data;
          } else {
            this.$message.error("请创建文章对应的标签后再发表文章");
            this.categoryData = [];
          }
        });
      },
      /**
       * 根据id获取文章信息
       */
      getArticleById() {
        if (this.$route.query.id != undefined) {
            getArticleById(this.$route.query.id).then(res => {
              if (res.code == 1) {
                let detail = res.data;
                // 处理content
                let raw = detail.articleContent;
                let regExp = new RegExp(PATH_SERVER_PLACEHOLDER, "gi");
                let articleContent = raw.replace(regExp, `${IMAGE_SERVER_URL}`);
                this.setContent(articleContent);
                // 处理coverImage，将coverImage通过data中的coverUrl传递给子组件
                this.entity.selectedCoverUrl = detail.coverImage;
                // 处理其他字段
                this.entity.id = detail.id;
                this.entity.articleTitle = detail.title;
                this.entity.editorType = detail.editorType;
                this.entity.selectedCategory = detail.categoryId;
                this.entity.selectedType = detail.type;
                this.entity.release = detail.isRelease;
                this.entity.summary = detail.summary;
                this.entity.ifExistedInCarousel = detail.ifExistedInCarousel;

                setTimeout(() => {
                  // 延迟500ms加载文章的标签，这是因为文章的标签数据是根据文章分类来的，所以当文章分类改变后，由于vue的监控，此时才会去加载标签的数据。
                  // 所以要等到标签的数据加载完成后再去给selectedTag赋值，此时才能回显信息
                  this.entity.selectedTag = detail.tags;
                }, 500)
              } else {
                this.$message({
                  type: 'error',
                  message: res.message
                });
                this.entity = {};
              }
            });
          }
      },
      /**
       * 跳转到markdown编辑器进行文章编辑
       */
      toMarkdown() {
        // 由于富文本编辑器的内容和markdown不能通用，所以要询问用户是否要切换
        this.$confirm('切换编辑器会清空已编辑的内容, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$router.push("/dashboard/article/markdown");
        }).catch(() => {});
      },
    },
    mounted () {
      // 1.初始化富文本编辑器
      this.initWangEditor();
      // 2.给categoryData赋值
      this.getAllCategory();
      // 3.如果url中传递id参数，那么要到后台拿取相关文章的信息
      this.getArticleById();
    },
    watch: {
      // 监听对于分类的选择，如果有改变就修改标签下拉框中的选项
      "entity.selectedCategory": function(newValue) {
        if (newValue != undefined) {
          // 清空已选项
          this.entity.selectedTag = [];
          // 根据分类id发送请求查询对应的标签
          getTagByCid(newValue).then(res => {
            if (res.code == 1) {
              this.tagData = res.data;
            } else {
              this.$message.error("请创建该分类下的标签后再进行选择");
              this.tagData = [];
            }
          });
        }

      }
    },
    components: {
      Card, SelectCoverTemplate
    },
    props: {
      editorDefault: {
        type: String,
        default: '<p><br/></p>'
      },
    },
  }

</script>

<style scoped>
  .toggle-editor {
    font-size: 14px;
    font-weight: bold;
    margin-left: 20px;
    display: inline-block;
    float: right;
    color: #333;
  }
  .toggle-editor:hover {
    font-size: 15px;
  }
  .rich-container {
    margin-top: 30px;
  }
  #websiteEditorElem {
    height: 450px;
  }
  .title-container {
    display: flex;
    justify-content: space-between;
  }
  .type-select {
    width: 80px;
    margin-right: 10px;
  }
  .category-select {
    width: 150px;
  }
  .tag-select {
    width: 180px;
  }
  h4 {
    color: #666;
    margin-top: 10px;
    margin-bottom: 10px;
  }
  .input-title {
    display: inline-block;
    width: 60%
  }
  .button-container {
    margin-top: 20px;
    text-align: right;
    position: relative;
  }
  .el-select {
    margin-right: 5px;
  }
</style>

<style>
  .el-select-dropdown__wrap, .el-scrollbar__wrap {
    margin-bottom: 0px !important
  }
  .el-popup-parent--hidden {
    padding-right: 0px !important;
  }

</style>
